package com.zhang.test.common.util;

import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import net.minidev.json.JSONObject;

import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;

public class TokenUtil {

    private static final byte[] secret = "rtyuiopghjkl;trhjm,yuiwertyui789461233333".getBytes();

    static class TokenUtilHolder {
        private final static TokenUtil instance = new TokenUtil();
    }

    public static TokenUtil getInstance() {
        return TokenUtilHolder.instance;
    }

    /**
     * 生成一个jwt token
     *
     * @param payloadMap
     * @return
     * @throws JOSEException
     */
    public String createToken(Map<String, Object> payloadMap) throws JOSEException {
        JWSHeader jwsHeader = new JWSHeader(JWSAlgorithm.HS256);

        Payload payload = new Payload(new JSONObject(payloadMap));

        JWSObject jwsObject = new JWSObject(jwsHeader, payload);

        JWSSigner jwsSigner = new MACSigner(secret);

        jwsObject.sign(jwsSigner);

        return jwsObject.serialize();
    }

    public Map<String, Object> valid(String token) throws ParseException, JOSEException {
        JWSObject jwsObject = JWSObject.parse(token);
        Payload payload = jwsObject.getPayload();

        JWSVerifier jwsVerifier = new MACVerifier(secret);
        Map<String, Object> resultMap = new HashMap<>();
        if (jwsObject.verify(jwsVerifier)) {
            resultMap.put("result", 0);
            JSONObject jsonObject = payload.toJSONObject();
            resultMap.put("data", jsonObject);
            if (jsonObject.containsKey("exp")) {
                Long expTime = Long.valueOf(jsonObject.getAsString("exp"));
                Long nowTime = System.currentTimeMillis();
                if (nowTime > expTime) {
                    resultMap.clear();
                    resultMap.put("result", 2);
                }
            }
        } else {
            resultMap.put("result", 1);
        }
        return resultMap;
    }

}
